// -*-c#-*-
// License: New BSD License : http://www.opensource.org/licenses/bsd-license.php
//
// Copyright (c) 2008, Brothers In Arms/Burl Nyswonger
//
// See: BiaVote.uc for full License
// 
//@L

class BiaVoteScene extends UTUIFrontEnd;

/* ------------------------------------------------------------------------- */

`include( BiaVote/Classes/BiaStdInc.uci );
`include( BiaVote/Classes/BiaVote.uci );

//
// cue's : StartGame, ServerSignIn, ServerSignOut
/* ------------------------------------------------------------------------- */


// Widgets...
//
// Customizable via .ini: BiaVoteTitle
// 
var transient UIList            lst_voteable, lst_votes;
var transient UIEditBox         fld_chat;
var transient UTUIComboBox      cbx_cat;
var transient UILabel           lbl_umessage, lbl_lmessage, lbl_clock;
var transient UTUIScene_MessageBox MBScene;

// Other...
var BiaVoteClient                BVC;
var UTUIDataStore_StringList    StringStore;
var UTPlayerController          UTPC;
var string                      sUmsg, sLmsg;
var bool                        bReady, bHaveNewMaps;
var array<string>               aCategories;
var int                         nSyncVer;

const ssWaitList = 'BiaVote__Wait';
const ssWaitBind = "<UTStringList:BiaVote__Wait>";
const ssWait     = "Wait...";

event SceneActivated(bool bInitialActivation)
{

    `BiaEnter();

    Super.SceneActivated(bInitialActivation);

    ConsoleCommand("SetShowScores false", false);

    PlayUISound( 'StartGame' );

    bReady = false;

    UMessage(ssWait);
    LMessage("");
    lbl_clock.SetDataStoreBinding( "--" );

    StringStore.Empty(ssWaitList);
    StringStore.AddStr(ssWaitList, ssWait, true);
    
    StringStore.Empty(`bv_vTypeToListName(vtCat), true);
    StringStore.Empty(`bv_vTypeToListName(vtGame), true);
    StringStore.Empty(`bv_vTypeToListName(vtMap), false);
    StringStore.AddStr(`bv_vTypeToListName(vtMap), ssWait, false);
    StringStore.Empty(`bv_vTypeToListName(vtKick), true);
    StringStore.Empty(`bv_vTypeToListName(vtVote), true);
    aCategories.Length = 0;
    
    
    lst_voteable.OnSubmitSelection = lst_SubmitSelection;
    lst_voteable.SetDataStoreBinding(`bv_vTypeToDsBinding( vtMap ));

    lst_votes.OnSubmitSelection = lst_SubmitSelection;
    
    lst_votes.SetDataStoreBinding( `bv_vTypeToDsBinding( vtVote ) );
    
    cbx_cat.OnValueChanged = cbx_OnValueChanged;
    cbx_cat.ComboList.SetDataStoreBinding( `bv_vTypeToDsBinding(vtCat) );
    
    fld_chat.OnSubmitText = fld_chat_SubmitText;
        

    // After all is set-up...
    BiaVoteClient_SceneActivated();
    
    `BiaExit();
}

function set_lbl( name nm, string txt )
{
    local UILabel uil;
    uil = UILabel(FindChild(nm, true));
    if( uil != None )
    {
        uil.SetDataStoreBinding(txt);
    }
    else
    {
        `BiaDbg("Unable to set datastorebinding for " $ nm );
    }
}

event PostInitialize()
{
    `BiaEnter();

    nSyncVer = -5;
    bHaveNewMaps = true;

    //
    // If more customizable stuff comes along, set it up here...
    set_lbl('BiaVoteTitle', "<BiaVoteDataStore:BiaVoteTitle>");
    
    //
    // static:
    //
    set_lbl('lbl_biavote_info', "[BIA]Vote, v" $ `BiaVoteVersion $ " -- http://code.google.com/p/ut3-sniper-game");

    lbl_umessage = UILabel(FindChild('lbl_umessage', true));
    lbl_lmessage = UILabel(FindChild('lbl_lmessage', true));
    lbl_clock = UILabel(FindChild('lbl_clock', true));
    lst_voteable = UIList(FindChild('lst_voteable', true));
    lst_votes = UIList(FindChild('lst_votes', true));
    cbx_cat = UTUIComboBox(FindChild('cbx_cat', true));
    fld_chat = UIEditBox(FindChild('fld_chat', true));

    if( UTPC == None )
    {
        UTPC = GetUTPlayerOwner();
    }
    
    if( StringStore == None && UTPC != None )
    {
        StringStore = UTUIDataStore_StringList(class'UTUIScene'.static.FindDataStore('UTStringList', LocalPlayer(UTPC.Player)));
    }
    
    Super.PostInitialize();
    
    `BiaExit();
}

event SceneDeactivated()
{
    BiaVoteClient_SceneDeactivated();
    Super.SceneDeactivated();
}

/* ticker:
function MyTick( int t )
{
}
*/


// ---------------------------------------------------------------------------
// Misc utility functions...

function Message( string txt, optional bool lower = false )
{
    if( lower )
    {
        sLmsg = txt;
        lbl_lmessage.SetDataStoreBinding( txt );
        PlayUISound('ListDown');
    }
    else
    {
        sUmsg = txt;
        lbl_umessage.SetDataStoreBinding( txt );
        PlayUISound('ListUp');
    }
}
function UMessage( string txt )
{
    Message(txt, false);
}
function LMessage( string txt )
{
    Message(txt, true);
}

function MyCloseScene()
{
    CloseScene(self);
}

function string MakeListItem( string Title, coerce string tag )
{
    local string res;
    
    res = title $ "                                                                                                                                        ";
    res = Left(res, 100);
    res = res $ ":" $ tag;
    
    return(res);
}
    

// ----------------------------------------------------------------------------
// UI Callbacks 

function OnDialogExitGame(UTUIScene_MessageBox MessageBox, int SelectedOption, int PlayerIndex)
{
    ButtonBar.PlayUIAnimation('FadeIn',,5.0);

    if (SelectedOption == 0)
    {
        MyCloseScene();
        ConsoleCommand("Quit");
    }
}

function OnDialogDisconnect(UTUIScene_MessageBox MessageBox, int SelectedOption, int PlayerIndex)
{
    ButtonBar.PlayUIAnimation('FadeIn',,5.0);

    if (SelectedOption == 0)
    {
        MyCloseScene();
        ConsoleCommand("Disconnect");
    }
}


function bool OnButtonbar_ExitGame(UIScreenObject InButton, int InPlayerIndex)
{
    MBScene = GetMessageBoxScene();
    if(MBScene != None)
    {
        ButtonBar.PlayUIAnimation('FadeOut',,5.0);
        MBScene.DisplayAcceptCancelBox("<Strings:UTGameUI.MidGameMenu.QuitGameWarning>","<Strings:UTGameUI.Campaign.Confirmation", OnDialogExitGame);
    }
    return true;
}

function bool OnButtonbar_Disconnect(UIScreenObject InButton, int InPlayerIndex)
{
    MBScene = GetMessageBoxScene();
    if(MBScene != None )
    {
        ButtonBar.PlayUIAnimation('FadeOut',,5.0);
        MBScene.DisplayAcceptCancelBox("Are you sure you want to disconnect?", "Disconnect", OnDialogDisconnect);
    }
    return true;
}

function bool OnButtonbar_Back(UIScreenObject InButton, int InPlayerIndex)
{
    MyCloseScene();
    return true;
}

function bool OnButtonbar_Score( UIScreenObject InButton, int PlayerIndex )
{
//
//TODO: find what happens in client-side GRI that disables input - if its re-enableable, then
// do another timer/tick hack if needed...
//
/*** Ick!  Still plenty of issues with GRI/PC and: ShowMidGameMenu(XX,XX, false); // disables input!!!
    local UTGameReplicationInfo GRI;
    local WorldInfo WI;
    
    WI = GetWorldInfo();
    
    if( WI != None )
    {
        GRI = UTGameReplicationInfo(WI.GRI);
    }
    
    if( GRI != None )
    {
        ButtonBar.PlayUIAnimation('FadeOut',,5.0);
        GRI.ShowMidGameMenu(UTPC, 'ScoreTab', true);
        return true;
    }
*/
    ConsoleCommand("SetShowScores true", false);
    MyCloseScene();
    return(true);
}

function lst_SubmitSelection( UIList Sender, Optional int PlayerIndex )
{
    local int Index, l, Id;
    local string title;
    
    `BiaDbg("list selection submitted: " $ Sender );
    
    Index = Sender.GetCurrentItem();
    title = Sender.GetElementValue( Index );
    
    Id = -1;
    l = Len(title) - 1;
    while(l > 1)
    {
        if( Mid(title, l-1, 1) == ":")
        {
            Id = int(Mid(title, l));
            break;
        }
        l = l - 1;
    }

    if( Id > -1 )
    {
        BVC.SubmitVote( Id );
        PlayUISound('ListSubmit');
    }
    else
    {
        PlayUISound('GenericError');
        UMessage("Submit Vote failed");
    }
    
    `BiaDbg("selected text value is: " $ title );
}

function SetComboList()
{
    local string oldcat, newcat;
    local int Index;
    
    Index = cbx_cat.ComboList.GetCurrentItem();
    oldcat = lst_voteable.GetDataStoreBinding();

    if( bHaveNewMaps )
    {
        newcat = "<UTStringList:BiaVoteCatMaps>";
    }
    else
    {
        newcat = "<UTStringList:BiaVoteCat" $ cbx_cat.ComboList.GetElementValue( Index ) $ ">";
    }
    
    if( oldcat != newcat )
        lst_voteable.SetDataStoreBinding(newcat);    
}

function cbx_OnValueChanged( UIObject Sender, int PlayerIndex )
{
    `BiaDbg("ComboBox Value Changed: " $ Sender );
    if( !bReady )
    {
        UMessage("Wait! - not ready yet...");
        PlayUISound('GenericError');
    }
    else
    {
        PlayUISound('ListSubmit');
        `BiaDbg("calling SetComboList()");
        SetComboList();
    }
}

function bool fld_chat_SubmitText( UIEditBox Sender, int PlayerIndex )
{
    local string msg;
    local bool res;

    `BiaEnter();

    res = false;
    
    msg = fld_chat.GetValue();

    if ( UTPC != none )
    {
        if ( UTPC.AllowTextMessage(msg) )
        {
            UTPC.ServerSay(msg);
            res = true;
        }
        else
        {
            `BiaDbg("Text Message disallowed.");
        }
    }
    
    if( res != true )
    {
        PlayUISound('GenericError');
    }
    else
    {
        PlayUISound('ListSubmit');
    }

    `BiaExit();
    
    return res;
}


// ----------------------------------------------------------------------------
// UI Class overrides...

function SetupButtonBar()
{
    if(ButtonBar != None)
    {
        ButtonBar.Clear();
        ButtonBar.AppendButton("Back", OnButtonbar_Back);
        ButtonBar.AppendButton("Score", OnButtonbar_Score);
        ButtonBar.AppendButton("Disconnect", OnButtonbar_Disconnect);
        ButtonBar.AppendButton("Exit Game", OnButtonbar_ExitGame);
//        ButtonBar.AppendButton("Settings", OnButtonbar_Back);
    }
}

function bool HandleInputKey( const out InputEventParameters EventParms )
{
    
    if( EventParms.InputKeyName == 'Escape' )
    {
        MyCloseScene();
        return(true);
    }
    
    return super.HandleInputKey( EventParms );
}

// ----------------------------------------------------------------------------
// Interface from BiaVoteClient ( BiaVoteClient calls these )
event TickTock( int Clock )
{
    lbl_clock.SetDataStoreBinding( string(Clock) );
}

function AckVote( string msg )
{
    UMessage( msg );
    PlayUISound('ListSubmit');
}

function ClientNakSync( string msg )
{
    `BiaError("Got a Nak from the sync operation");
    UMessage( msg );
    LMessage("");
    PlayUISound('GenericError');
}

function ClientAckSync( string msg, bool bOnlyVotes = false )
{
    `BiaDbg("Got ack - bOnlyVotes is: " $ bOnlyVotes);
    LMessage("");
    if( bOnlyVotes )
    {
        ReSync( BVC.UILists, true );
    }
    else
    {
        if( msg != "" )
        {
            UMessage( msg );
        }
        PlayUISound('RefreshServers');
        PlayUISound('SignIn');
    }
}

function ClientStartSync( string msg, optional bool bNewMaps )
{
    bHaveNewMaps = bNewMaps;
    `BiaDbg("bHaveNewMaps: " $ bHaveNewMaps);
    LMessage(msg);
}

event ReSync( array<sUIList> uil, bool bOnlyVotes = false )
{
    local sUIList s;
    local string title;
    local array<string> SawList;
    local array<sUIList> aVotes;
    local bool bNewCat;
    local string ListName;

    `BiaEnter();
    `BiaDbg("bHaveNewMaps: " $ bHaveNewMaps);
    `BiaDbg("bOnlyVotes  : " $ bOnlyVotes);
    
    if( !bOnlyVotes )
    {
        UMessage("Wait, Syncing Lists....");
    }
  
    aVotes.Length = 0;
    bNewCat = false;
    
    foreach uil(s)
    {
        if( s.vType == vtNone || s.Id == 0 || s.Id == vtProperty )
        {
            `BiaDbg("Skipping item " $ s.Title);
            continue;
        }

        if( s.vType == vtVote )
        {
            s.Id = ( s.Id & ~16384 );
            s.Title = MakeListItem(s.Title, s.Id);
            `BiaDbg("Adding a vote: " $ s.Id $ ", nVotes:" $s.nVotes$", Title:" $ s.Title );
            aVotes.AddItem( s );
            
            if( bOnlyVotes )
            {
                continue;   
            }
        }
        
        if( s.vType == vtCat )
        {
            title = s.Title;
            if( aCategories.Find( title ) < 0 )
            {
                `BiaDbg("First time I found this in aCategories[] : " $ title );
                aCategories.AddItem( title );
                bNewCat = true;
            }
            continue;
        }

        ListName = `bv_vTypeToListString( s.vType );

        if( ListName != `bv_vTypeUnlisted )
        {
            if( SawList.Find( ListName ) < 0)
            {
                StringStore.Empty(name(ListName), false);
                SawList.AddItem( ListName );
            }
            
            title = MakeListItem( s.Title, s.Id );
            `BiaDbg("Adding to list " $ ListName $ ", Id:" $s.Id$ ", Title: " $ title );
            StringStore.AddStr(name(ListName), title, false);
            
        }
    }

    if( aVotes.Length > 0 )
    {
        `BiaDbg("Adding Votes...");
        AddVotes( aVotes );
    }
    
    bReady = true;

    if( bNewCat || bHaveNewMaps )
    {
        `BiaDbg("new categories happened...");
        StringStore.Empty(`bv_vTypeToListName(vtCat), false);
        foreach aCategories(title)
        {
            `BiaDbg("Adding Category: " $ title );
            StringStore.AddStr(`bv_vTypeToListName(vtCat), title, false);
        }
        `BiaDbg("Calling SetComboList()");
        SetComboList();
        bHaveNewMaps = false;
    }
    
    if(`iInstr(sUmsg, "wait") == 0)
    {
        UMessage("");
    }
    //TODO: fix all the sync messages... - aaagh!
    
    `BiaExit();
}

function AddVotes( array<sUIList> aVotes )
{
    local int i, j;
    local array<int> aMax, aIdx;
    local bool bInserted;
    local string title;
    
    `BiaEnter();
    
    aMax.Length = 0;
    aIdx.Length = 0;
    
    for(i=0; i< aVotes.Length; i++)
    {
        if( aVotes[i].nVotes > 0 )
        {
            bInserted = false;
            for(j=0; j < aMax.Length; j++)
            {
                if( aMax[j] < aVotes[i].nVotes )
                {
                    aMax.Insert(j, 1);
                    aIdx.Insert(j, 1);
                    `BiaAssert( aMax.Length == aIdx.Length );
                    aMax[j] = aVotes[i].nVotes;
                    aIdx[j] = i;
                    bInserted = true;
                    break;
                }
            }
            if( !bInserted )
            {
                j = aMax.Length;
                aMax.Add(1);
                aIdx.Add(1);
                `BiaAssert( aMax.Length == aIdx.Length );
                aMax[j] = aVotes[i].nVotes;
                aIdx[j] = i;
            }
        }
    }
    
    `BiaAssert( aMax.Length == aIdx.Length );
    StringStore.Empty(`bv_vTypeToListName(vtVote), false);
    for(i = 0; i < aIdx.Length; i++)
    {
        j = aIdx[i];
        `BiaAssert( j > -1 && j < aVotes.Length );
        title = "[" $ aVotes[j].nVotes $ "] " $ aVotes[j].Title;
        StringStore.AddStr(`bv_vTypeToListName(vtVote), title, false);
    }
    
    `BiaExit();
}

// ----------------------------------------------------------------------------
// Interface to BiaVoteClient

function BiaVoteClient_SceneActivated()
{
    local BiaVoteClient B;
    
    `BiaEnter();

    if( BVC == None )
    {
        `BiaDbg("finding BiaVoteClient (BVC)");
        ForEach PlayerOwner.GetCurrentWorldInfo().AllActors(class'BiaVote.BiaVoteClient', B)
        {
            if( B.MyPlayerController == UTPC )
            {
                if( BVC == None )
                {
                    `BiaDbg("setting BVC to: " $ B);
                    BVC = B;
                }
                else
                {
                    `BiaError("Multiple BiaVoteClient objects exist: " $ B );
                }
            }
        }
    }
    
    if( BVC != None )
    {
        BVC.UIActivated( self );
//        BVC.UISync();
    }
    
    `BiaExit();        
}

function BiaVoteClient_SceneDeactivated()
{
    if( BVC != None )
    {
        BVC.UIDeactivated();
        BVC = None;
    }
}

function UnRef()
{
    CloseScene(self);
    BVC = None;
    UTPC = None;
}

defaultproperties
{

}
